package es.wtestgen.services;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Restrictions;

import es.wtestgen.domain.Alumno;
import es.wtestgen.domain.Asignatura;
import es.wtestgen.domain.Examen;
import es.wtestgen.domain.Pregunta;
import es.wtestgen.domain.Profesor;
import es.wtestgen.domain.Respuesta;
import es.wtestgen.util.HibernateUtil;

public class WTestGenService<E> {
	
	private static final Log log = LogFactory.getLog(HibernateUtil.class);
	
	private static WTestGenService instance = null;
	
	protected WTestGenService(){
		
	}
	
	public static WTestGenService getInstance(){
		if(instance == null){
			instance = new WTestGenService();
		}
		return instance;
	}	

	public boolean autenticarAlumno(String usuario, String password, HttpServletRequest request) 
								throws HibernateException{				
		/*
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.openSession();
		*/
		boolean autenticado = false;
		try{
			Session session = HibernateUtil.currentSession();
			
			Query query = session.createQuery("from Alumno a where a.nombreUsua = :nombreUsua and a.pwdUsua = :pwdUsua");
			
			query.setString("nombreUsua", usuario);
			query.setString("pwdUsua", password);
									
			List alumnos = new ArrayList<Alumno>(); 
			alumnos = (ArrayList<Alumno>)query.list();
			
			if(alumnos == null || alumnos.size()<1){
				autenticado = false;
			}else{			
				Alumno alumno = (Alumno)alumnos.get(0);
				/*
				 * se mete en sesion el objeto alumno (usuario) para controlar el acceso a la
				 * aplicacion y la gestion de roles  
				 */
				request.getSession().setAttribute("alumno", alumno);
				autenticado = true;
			}		
		}catch(HibernateException e){
			log.error("_____Error al obtener la sesion de hibernate: "+e,e);
			throw new HibernateException(e);						
		}
		return autenticado;
	}
	
	public boolean autenticarProfesor(String usuario, String password, HttpServletRequest request) {				
		/*
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.openSession();
		*/
		boolean autenticado = false;
		try{
				Session session = HibernateUtil.currentSession();
			
				Criteria criteria = session.createCriteria(Profesor.class);
				criteria.add(Restrictions.eq("nombreUsua", usuario));
				criteria.add(Restrictions.eq("pwdUsua",password));
										
				List profesores = new ArrayList<Profesor>(); 
				profesores = (ArrayList<Profesor>)criteria.list();
				
				if(profesores == null || profesores.size()<1){
					autenticado = false;
				}else{			
					Profesor profesor = (Profesor)profesores.get(0);
					
					request.getSession().setAttribute("profesor", profesor);
					autenticado = true;
				}
		}catch(HibernateException e){
			log.error("_____Error al obtener la sesion de hibernate: "+e,e);
			throw new HibernateException(e);						
		}
		return autenticado;		
		
	}
	

	public void salir(String usuario) {
		// TODO Auto-generated method stub
		
	}	
	
	
	public List findAll(String clase){
		List lista = new ArrayList();
		Criteria criteria = null;
		
		try{
			Session session = HibernateUtil.currentSession();
			if(clase.equals("Alumno")){
				criteria = session.createCriteria(Alumno.class);				
			}else if(clase.equals("Asignatura")){
				criteria = session.createCriteria(Asignatura.class);
			}else if(clase.equals("Examen")){
				criteria = session.createCriteria(Examen.class);
			}else if(clase.equals("Pregunta")){
				criteria = session.createCriteria(Pregunta.class);
			}else if(clase.equals("Respuesta")){
				criteria = session.createCriteria(Respuesta.class);
			}
			lista = criteria.list();		
		}catch(HibernateException e){
			log.error("_____Error al obtener la todos los registros de la clase "+ clase + ": "+e,e);
			throw new HibernateException(e);						
		}	
		return lista;
	}
	
	
	public List findById(String clase, String cod){
		List lista = new ArrayList();
		Criteria criteria = null;
		int id = Integer.parseInt(cod);
		
		try{
			Session session = HibernateUtil.currentSession();
			if(clase.equals("Alumno")){
				criteria = session.createCriteria(Alumno.class);				
				criteria.add(Restrictions.eq("codAlum", id));
			}else if(clase.equals("Asignatura")){
				criteria = session.createCriteria(Asignatura.class);
				criteria.add(Restrictions.eq("codAsig", id));
			}else if(clase.equals("Examen")){
				criteria = session.createCriteria(Examen.class);
				criteria.add(Restrictions.eq("codExam", id));
			}else if(clase.equals("Pregunta")){
				criteria = session.createCriteria(Pregunta.class);
				criteria.add(Restrictions.eq("codPreg", id));
			}else if(clase.equals("Respuesta")){
				criteria = session.createCriteria(Respuesta.class);
				criteria.add(Restrictions.eq("codResp", id));
			}
			lista = criteria.list();		
		}catch(HibernateException e){
			log.error("_____Error al obtener el registro de la clase "+ clase + ": "+e+" con id: " + id,e);
			throw new HibernateException(e);						
		}	
		return lista;
	}
	
	
	public boolean guardar(String clase,Object obj){
		Transaction tx = null;
		Session session = HibernateUtil.currentSession();
		boolean guardado = false;
		try{			
			tx = session.beginTransaction();
			session.clear();
			//session.flush();
			if(clase.equals("Alumno")){				
				session.saveOrUpdate((Alumno)obj);
			}else if(clase.equals("Asignatura")){
				session.saveOrUpdate((Asignatura)obj);
			}else if(clase.equals("Examen")){
				session.saveOrUpdate((Examen)obj);
			}else if(clase.equals("Pregunta")){
				session.saveOrUpdate((Pregunta)obj);
			}else if(clase.equals("Respuesta")){
				session.saveOrUpdate((Respuesta)obj);
			}
			tx.commit();
			guardado = true;
		}catch(Exception e){
			try{
				tx.rollback();
			}catch(Exception e2){
				
			}
		}finally{
				HibernateUtil.closeSession();
		}
		return guardado;
	}
	
	
	public boolean eliminar(String clase,Object obj){
		Transaction tx = null;
		Session session = HibernateUtil.currentSession();
		boolean eliminado = false;
		try{			
			tx = session.beginTransaction();
			if(clase.equals("Alumno")){
				session.delete((Alumno)obj);
			}else if(clase.equals("Asignatura")){
				session.delete((Asignatura)obj);
			}else if(clase.equals("Examen")){
				session.delete((Examen)obj);
			}else if(clase.equals("Pregunta")){
				session.delete((Pregunta)obj);
			}else if(clase.equals("Respuesta")){
				session.delete((Respuesta)obj);
			}
			tx.commit();
			eliminado = true;
		}catch(Exception e){
			try{
				tx.rollback();
			}catch(Exception e2){
				
			}
		}finally{
				HibernateUtil.closeSession();
		}
		return eliminado;
	}
	
	public List findAsignaturasProfesor(Profesor profesor){
		List asignaturas = new ArrayList();
		Criteria criteria = null;
		//int id = Integer.parseInt(codProf);
		
		try{
			Session session = HibernateUtil.currentSession();
			criteria = session.createCriteria(Asignatura.class);
			//criteria.add(Restrictions.eq("fk_codProf", profesor.getCodProf()));
			criteria.add(Expression.eq("profesor", profesor));
			asignaturas = criteria.list();		
		}catch(HibernateException e){
			log.error("_____Error al obtener las asignaturas del profesor: "+ profesor.getNombre() + " " + profesor.getApellidos(),e);
			throw new HibernateException(e);						
		}	
		
		return asignaturas;
		
	}
	public Set findAlumnosAsignatura(Asignatura asignatura){
		Set alumnos = new HashSet();
		
		try{
			Session session = HibernateUtil.currentSession();
			
			Asignatura asig = (Asignatura)session.get(Asignatura.class, asignatura.getCodAsig());
			
			alumnos = asig.getAlumnos();

		}catch(HibernateException e){
			log.error("_____Error al obtener los alumnos de la asignatura: "+ asignatura.getNombreAsig() ,e);
			throw new HibernateException(e);						
		}	
		
		return alumnos;
		
	}
	
	
	public boolean guardarAlumnoEnAsignatura(String clase, Alumno alum,String codAsig){
		Transaction tx = null;
		Session session = HibernateUtil.currentSession();
		boolean guardado = false;
		try{			
			tx = session.beginTransaction();
			session.clear();
			//session.flush();
			
			Asignatura asignatura = (Asignatura)session.get(Asignatura.class,Integer.parseInt(codAsig));
			alum.getAsignaturas().add(asignatura);
			
			session.saveOrUpdate(alum);
			Alumno alumno = (Alumno)session.get(Alumno.class,alum.getCodAlum());
			asignatura.getAlumnos().add(alumno);
			session.saveOrUpdate(asignatura);
			
			tx.commit();
			guardado = true;
		}catch(Exception e){
			try{
				tx.rollback();
			}catch(Exception e2){
				
			}
		}finally{
				HibernateUtil.closeSession();
		}
		return guardado;
	}

}
